home *** CD-ROM | disk | FTP | other *** search
- (**********************************************************************)
- (* *)
- (* Function: UART Universal Asynchronous Receiver / Transmitter *)
- (* *)
- (* Creation Date: 27/Jul/92 From: NEW *)
- (* *)
- (* Author: Josef Fuchs / Ewald Liess *)
- (* *)
- (* Description: *)
- (* ------------ *)
- (* This function uses 1 or 2 TPU channels to form a uni or bidirection*)
- (* UART. Baud rate is freely programmable by the user. The data word *)
- (* length can be between 1 and 14 bits and no/odd/even parity is *)
- (* supported. The function has been designed to operate in a similar *)
- (* manner to the SCI port found on many Motorola MCUs. The function is*)
- (* double buffered i.e there is a shift reg. and data reg. *)
- (* All 16 TPU channels could be used for UART, each operating at more *)
- (* than 9600 baud. *)
- (* *)
- (* Updates: By: Modification: *)
- (* -------- --- ------------- *)
- (* RevB JW Added interrupt generation to transmitter init *)
- (* - state2 *)
- (* 16/Jun/93 JW Moved receiver interrupt generation to be after *)
- (* data write for correct polled operation. *)
- (* Designated as rev 1.0 for mask release. *)
- (* 12/Aug/93 JL Converted to new TPUMASM syntax *)
- (* *)
- (*--------------------------------------------------------------------*)
- (* Standard Exits Used:- End_Of_Phase: N End_Of_Link: Y *)
- (* *)
- (* External Files included: NONE *)
- (* *)
- (* CODE SIZE excluding standard exits = 67 LONG WORDS *)
- (*--------------------------------------------------------------------*)
- (* *)
- (* *)
- (********** This Revision: 1.1 *********)
- (* *)
- (********** LAST MODIFIED: 12/Aug/93 BY: Jeff Loeliger ********)
- (* *)
- (**********************************************************************)
- (***************************************************************************)
- (*Motorola reserves the right to make changes without further notice to any*)
- (*product herein. Motorola makes no warranty, representation or guarantee *)
- (*regarding the suitability of its products for any particular purpose, nor*)
- (*does Motorola assume any liability arising out of the application or use *)
- (*of any product or circuit, and specifically disclaims any and all *)
- (*liability, including without limitation consequential or incidental *)
- (*damages. "Typical" parameters can and do vary in different applications. *)
- (*All operating parameters, including "Typical",must be validated for each *)
- (*customer application by customer's technical experts. Motorola does not *)
- (*convey any license under its patent rights nor the rights of others. *)
- (*Motorola products are not designed, intended, or authorized for use as *)
- (*components in systems intended for surgical implant into the body, or *)
- (*other applications intended to support or sustain life, or for any other *)
- (*application in which the failure of the Motorola product could create a *)
- (*situation where injury or death may occur. Should Buyer purchase or use *)
- (*Motorola products for any such unintended or unauthorized application, *)
- (*Buyer, shall indemnify and hold Motorola and its officers, employees, *)
- (*subsidiaries, affiliates, and distributors harmless against all claims, *)
- (*costs, damages, and expenses, and reasonable attorney fees arising out *)
- (*of, directly or indirectly, any claim of personal injury or death *)
- (*associated with such unintended or unauthorized use, even if such claim *)
- (*alleges that Motorola was negligent regarding the design or manufacture *)
- (*of the part. *)
- (*Motorola and the Motorola logo are registered trademarks of Motorola Inc.*)
- (*Motorola is an Equal Opportunity/Affirmative Action Employer. *)
- (*Copyright Motorola Inc. 1993 *)
- (***************************************************************************)
-
-
- (*()()()()()()()()()()() DATA STRUCTURE ()()()()()()()()()()()()()()()*)
- (* *)
- (* name: Written By: Location Bits: *)
- (* ----- ----------- --------------- *)
- (* PARITY_TEMP TPU Parameter0 0..15 *)
- (* Used by TPU to calculate parity - CPU must not *)
- (* write. *)
- (* *)
- (* MATCH_RATE CPU Parameter1 0..15 *)
- (* Baud period in TCR1 clocks. *)
- (* *)
- (* DATA BOTH Parameter2 0..15 *)
- (* Transmit or Receive data register. For transmit*)
- (* ,bit 15 must be 0. *)
- (* *)
- (* DATA_SIZE CPU Parameter3 0..15 *)
- (* Holds the number of bits in a data word - *)
- (* INCLUDING parity. *)
- (* *)
- (* ACTUAL_BIT_COUNT TPU Parameter4 0..15 *)
- (* Used by the TPU to count the number of bits. *)
- (* CPU must not write. *)
- (* *)
- (* SHIFT_REG TPU Parameter5 0..15 *)
- (* Used by the TPU for shifting in/out data. *)
- (* CPU must not write. *)
- (* *)
- (* *)
- (* HSQ1 HSQ0 Action *)
- (* ---- ---- ------ *)
- (* 0 0 No Parity. *)
- (* 0 1 No Parity. *)
- (* 1 0 Even Parity. *)
- (* 1 1 Odd Parity. *)
- (* *)
- (* hsr1 hsr0 Action *)
- (* ---- ---- ------ *)
- (* 0 x No action *)
- (* 1 0 Initialise channel as receiver. [clfg1 cleared]*)
- (* 1 1 Initialise chan as transmitter. [cflg1 set] *)
- (* *)
- (* Links Accepted: NO Links Generated: NO *)
- (* *)
- (* Interrupts Generated After: Transmit data empty/receive data full*)
- (* *)
- (*()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()*)
-
- (*+++++++++++++++++++++ PARAMETER MACROS +++++++++++++++++++++++++++*)
-
- %macro PARITY_TEMP_UART 'prm0'.
- %macro MATCH_RATE_UART 'prm1'.
- %macro DATA_UART 'prm2'.
- %macro DATA_SIZE_UART 'prm3'.
- %macro ACTUAL_BIT_COUNT_UART 'prm4'.
- %macro SHFT_REG_UART 'prm5'.
-
- (* conditions *)
- %macro RECEIVER_UART 'flag1 = 0'. (* Receiver is selected by cflag1=0 *)
- %macro PARITY_OFF_UART 'hsq1 = 0'. (* no Parity *)
- %macro PARITY_EVEN_UART 'hsq0 = 0'. (* use even Parity *)
-
-
- (*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*)
-
-
- (*====================================================================*)
- (*||||||||||||||||||||| MICROCODE STARTS BELOW |||||||||||||||||||||*)
- (*VVVVVVVVVVVVVVVVVVVVV--------------------------VVVVVVVVVVVVVVVVVVVVV*)
-
-
-
- (**********************************************************************)
- (* *)
- (* State 1: Initialisation for RECEIVER *)
- (* *)
- (* entered by HSR 2 *)
- (**********************************************************************)
-
- %entry start_address *;disable_match;
- name = INIT_RECEIVER_UART;
- cond hsr1 = 1, hsr0 = 0.
-
- INIT_RECEIVER_UART: chan tbs := in_m1_c1,
- pac := high_low;
- chan clear flag0; (*wait for start-bit = falling edge *)
- enable_mtsr.
-
- chan neg_tdl, neg_mrl, neg_lsl;
- chan clear flag1; (* select RECEIVER *)
- end.
-
-
-
- (**********************************************************************)
- (* *)
- (* State 2: Initialisation for TRANSMITTER *)
- (* *)
- (* entered by HSR 3 *)
- (**********************************************************************)
-
- %entry ram p <- @MATCH_RATE_UART; start_address *;disable_match;
- name = INIT_TRANSMIT_UART;
- cond hsr1 = 1, hsr0 = 1.
-
- INIT_TRANSMIT_UART: chan tbs := out_m1_c1,
- pac := no_change,
- pin := high;
- chan clear flag0; (* poll the TDRE-bit *)
- enable_mtsr.
-
- au ert := tcr1 + p;
- chan neg_tdl, neg_mrl, neg_lsl;
- write_mer;
- chan set flag1; (* select TRANSMITTER *)
- chan cir; (* revB - for IRQ driven transmitter *)
- end.
-
-
-
- (**********************************************************************)
- (* *)
- (* if TRANSMITTER then State 3: POLLING TDRE *)
- (* else RECEIVER then goto STATE 5: FALLING EDGE DETECTED *)
- (* *)
- (* For Transmitter: *)
- (* entered after a match if no data is sent out, then: *)
- (* if TDRE is set: set up next match to test TDRE again *)
- (* else set cflag0 to indicate transmittion and send startbit *)
- (* *)
- (* For Receiver: *)
- (* entered after a falling edge (of startbit) is detected, *)
- (* then goto State 5 (receive startbit) *)
- (**********************************************************************)
-
- %entry ram diob <- @MATCH_RATE_UART; start_address *; disable_match;
- name = SERV_START_BIT_UART;
- cond hsr1 = 0, hsr0 = 0, m/tsr = 1,lsr = 0, pin = x,flag0 = 0.
-
- SERV_START_BIT_UART:
- if @RECEIVER_UART then goto RXD_START_BIT_UART.
- (* Goto Receiver *)
-
- au p := 0;
- ram p -> @PARITY_TEMP_UART. (* reset high-bit counter *)
-
- (* following statements are for transmitter only *)
-
- au ert := ert + diob; (* define first match *)
- chan neg_mrl, neg_lsl, neg_tdl;
- write_mer.
-
- ram p <- @DATA_UART.
-
- au nil := p, ccl; (* test TDRE *)
- ram diob <- @DATA_SIZE_UART.
-
- if N = 1 then goto END_OF_LINK,flush.
-
- (* valid data found, send it *)
-
- SEND_START_BIT_UART:
- chan pac := low; (* start bit *)
- chan set flag0; (* now send data *)
- chan cir.
-
- au diob := diob+1; (* count also startbit *)
- ram diob -> @ACTUAL_BIT_COUNT_UART.
-
- au p := p + max; (* chan set TDRE-Bit = MSB *)
- ram p -> @SHFT_REG_UART. (* copy data to shift register *)
-
- ram p -> @DATA_UART; (* chan set TDRE in Dataword *)
- end.
-
-
-
- (**********************************************************************)
- (* *)
- (* if TRANSMITTER then State 4: send data bits *)
- (* else if RECEIVER then goto STATE 6: receive data bits *)
- (* *)
- (* Read the Data and shift the LSB-Bit out, then write the shifted *)
- (* value into the SHFT_REG and decrement ACTUAL_BIT_COUNT. *)
- (**********************************************************************)
-
- %entry ram diob <- @MATCH_RATE_UART; start_address *; disable_match;
- name = SERV_DATA_BITS_UART;
- cond hsr1 = 0, hsr0 = 0, m/tsr = 1, lsr = 0, pin = x, flag0 = 1.
-
- SERV_DATA_BITS_UART:
- au ert := ert + diob;
- ram p <- @ACTUAL_BIT_COUNT_UART.
-
- if @RECEIVER_UART then goto RXD_DATA_BIT_UART.
- (* Goto Receiver *)
-
- au p := p - 1, ccl; (* decrement number of bits *)
- ram p -> @ACTUAL_BIT_COUNT_UART.
-
- (* following statements are for transmitter only *)
-
- if N = 1 then goto SEND_STOP_BIT_UART,flush.
-
- if Z = 1 then goto SEND_PARITY_UART,flush.
-
- ram p <- @SHFT_REG_UART.
-
- ram diob <- @PARITY_TEMP_UART.
-
- SEND_BIT_UART: au p :=>> p, ccl; (* shift out data bit *)
- ram p -> @SHFT_REG_UART.
-
- if C = 1 then goto SEND_HIGH_BIT_UART,flush.
-
- SEND_LOW_BIT_UART:
- chan pac := low;
- neg_tdl, neg_lsl, neg_mrl;
- write_mer;
- end.
-
- SEND_HIGH_BIT_UART:
- au diob:= diob+1; (* update parity *)
- ram diob -> @PARITY_TEMP_UART.
-
- chan pac := high;
- neg_tdl, neg_lsl, neg_mrl;
- write_mer;
- end.
-
- SEND_PARITY_UART:
- if @PARITY_OFF_UART then goto SEND_STOP_BIT_UART,flush.
-
- if @PARITY_EVEN_UART then goto SEND_BIT_UART.
-
- ram p <- @PARITY_TEMP_UART.
-
- goto SEND_BIT_UART.
-
- au p := p + 1. (* generate odd parity = do a complement *)
-
- SEND_STOP_BIT_UART:
- chan pac := high;
- neg_tdl, neg_lsl, neg_mrl;
- write_mer;
- chan clear flag0;
- end.
-
-
- (**********************************************************************)
- (* *)
- (* STATE 5: FALLING EDGE DETECTED *)
- (* *)
- (* START-Bit and start sampling in the middle of a BIT *)
- (* = set up a match after 1.5 bittimes *)
- (* *)
- (* Parity Temp already cleared, diob contains Matchrate *)
- (* *)
- (**********************************************************************)
-
- RXD_START_BIT_UART:
- au ert:=ert+diob;
- ram p <- @DATA_SIZE_UART.
-
- if @PARITY_OFF_UART then goto RXD_NO_PARITY_UART,flush.
-
- au p := p + 1. (* count also parity bit if enabled *)
-
- RXD_NO_PARITY_UART:
- ram p -> @ACTUAL_BIT_COUNT_UART;
- au diob :=>> diob. (* MATCHRATE/2 *)
-
- au ert := ert + diob; (* ert := ert +1.5*Matchrate *)
- chan pac := no_detect; chan set flag0;
- neg_mrl, neg_lsl, neg_tdl;
- write_mer;
- end.
-
-
-
- (**********************************************************************)
- (* *)
- (* STATE 6: RECEIVE BITS *)
- (* *)
- (* Read the value at the pin and shift this value in the SHFT_REG. *)
- (* Also decrement ACTUAL_BIT_CNT (the number of received bits). *)
- (* *)
- (* diob contains Matchrate, ert already set up with ert+diob *)
- (* no write_mer issued !! *)
- (* Actual_Bit_Count is already decremented ccl set by decrement *)
- (**********************************************************************)
-
- RXD_DATA_BIT_UART:
- if N = 1 then goto RECEIVE_STOP_UART.
-
- au a := 0; (* clear FLAG-BITS *)
- ram diob <- @SHFT_REG_UART. (* read shiftregister *)
-
- (* there is a data bit to receive *)
-
- if psl = 1 then goto RECEIVE_HIGH_UART.
- (* high bit has to be received *)
- au diob :=>> diob; (* shift zero into BIT15 *)
- chan neg_tdl, neg_lsl, neg_mrl;
- write_mer.
-
- RECEIVE_LOW_UART:
- ram diob -> @SHFT_REG_UART; (* get the low bit *)
- end.
-
- RECEIVE_HIGH_UART:
- au diob := diob + max; (* chan set received bit, shifted before *)
- ram diob -> @SHFT_REG_UART.
-
- ram diob <- @PARITY_TEMP_UART. (* add parity *)
-
- au diob := diob + 1; (* count an additional high bit *)
- ram diob -> @PARITY_TEMP_UART;
- end.
-
- (* all data bits have been received and stored left justified in the shift- *)
- (* register if parity was enabled, parity is in BIT15 of the shift register *)
-
- RECEIVE_STOP_UART:
- if psl = 1 then goto RXD_OK_UART, flush.
- (*stopbit must be high *)
-
- SET_FE_FLAG_UART: au a :=>> max.
- (* set Framing Error if stopbit was not high *)
- (* stores $4000 into a, sets Bit 14 *)
-
- (* now check the parity *)
- RXD_OK_UART:
- if @PARITY_OFF_UART then goto PAR_OK_UART,flush.
- (* Parity enabled ? *)
-
- au diob :=<< diob; (* remove Parity *)
- ram p <- @PARITY_TEMP_UART.
-
- if @PARITY_EVEN_UART then goto EVEN_PAR_UART,flush.
-
- au p := p + 1. (* for odd parity, negate it *)
-
- EVEN_PAR_UART: au nil :=>> p,ccl. (* copy LSB from PARITY_TEMP to Carry *)
-
- if C = 0 then goto PAR_OK_UART,flush.
-
- (* there was a parity error *)
- au a := a + max. (*set Parity error, $8000, Bit 15 chan set*)
-
- (* now move the left justified value in the shiftregister to right *)
- (* to have a right justified result *)
-
- PAR_OK_UART: ram p <- @DATA_SIZE_UART.
-
- (* calculate number of bits to shift right *)
-
- au dec := dec - p; (* align to the right side *)
- chan pac := high_low; (* init for new startbit *)
- chan clear flag0;neg_tdl,neg_mrl.
-
- repeat;
- au diob :=>> diob. (* align data right *)
-
- au diob := diob + a; (* combine data and flags *)
- ram diob -> @DATA_UART. (* and store received dataword *)
-
- chan cir; (* generate RDRF-interrupt *)
- end.
-
-
-
- (**********************************************************************)
- (* UNDEFINED ENTRIES - execute an end. *)
- (**********************************************************************)
- %entry start_address END_OF_LINK;
- name = UART_UNDEF;
- cond hsr1 = 0,hsr0 = 1.
-
- %entry start_address END_OF_LINK; disable_match;
- name = UART_UNDEF;
- cond hsr1 = 0, hsr0 = 0, m/tsr = 0, lsr = 1, pin = x, flag0 = x.
-
- %entry start_address END_OF_LINK; disable_match;
- name = UART_UNDEF;
- cond hsr1 = 0, hsr0 = 0, m/tsr = 1, lsr = 1, pin = x, flag0 = x.
-